(function(global, factory) {
  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('hy5b/t/frontend')) :
    typeof define === 'function' && define.amd ? define(['frontend'], factory) :
    global.t = factory(t);
}(this, function(T) {
  'use strict';

  var ctest = function(sid) {
    this.sid_ = sid || '_st_ctest';
    this.dom_ = T.id(this.sid_);

    var self = this;
    if (!self.dom_) {
      var elem = document.createElement("div");
      elem.id = self.sid_;
      document.body.appendChild(elem);
      self.dom_ = elem;
      window.onscroll = function() {
        self.resetPosition();
      }
    }
    self.dom_.className = "ctest";
    self.dom_.style.display = "none";
    self.time_ = new Date();
    self.torigin_ = self.time_;
    return this;
  };

  ctest.prototype.resetPosition = function() {
    var oscroll = T.getScrollPos();
    var dom = this.dom_;
    dom.style.display = "block";
    //dom.style.left = (oscroll.x + 5).toString() + "px";
    dom.style.top = (oscroll.y + 5).toString() + "px";
  }

  ctest.prototype.add = function(scontent) {
    var now = new Date();
    var duration = now.getTime() - this.time_.getTime();
    var dorigin = now.getTime() - this.torigin_.getTime();
    var dom = this.dom_;
    if (dom) {
      this.resetPosition();
      var elem = document.createElement("div");
      var smsg = "",
        params;
      if (scontent.callee) {
        params = scontent;
      } else {
        params = arguments;
      }
      for (var i = 0; i < params.length; i++) {
        smsg += params[i] + " | ";
      }
      elem.innerHTML = "<strong>+" + duration + "ms, total:" + dorigin + "ms:</strong> " + smsg;
      dom.appendChild(elem);
      dom.scrollTop = dom.scrollHeight;
    }
    this.time_ = new Date();
    return this;
  }

  ctest.prototype.show = function(scontent) {
    var now = new Date();
    var duration = now.getTime() - this.time_.getTime();
    var dorigin = now.getTime() - this.torigin_.getTime();
    var dom = this.dom_;
    if (dom) {
      this.resetPosition();
      var smsg = "",
        params;
      if (scontent.callee) {
        params = scontent;
      } else {
        params = arguments;
      }
      for (var i = 0; i < params.length; i++) {
        smsg += params[i] + " | ";
      }
      dom.innerHTML = "<div><strong>+" + duration + "ms, total:" + dorigin + "ms:</strong> " + smsg + "</div>";
    }
    this.time_ = new Date();
    return this;
  }

  ctest.prototype.popId = function() {
    return this.sid_;
  }

  ctest.prototype.popDom = function() {
    return this.dom_;
  }

  var funx = { CTest: ctest };

  var otest = null;

  funx.ctest = function(id) {
    if (otest) {
      return otest;
    } else {
      otest = new ctest(id);
      return otest;
    }
  }

  funx.S = function() {
    if (otest)
      return otest.add.apply(otest, arguments);
    else {
      otest = new ctest;
      //this.CDialog({title:"u5A04u5A77\u6D4B\u8BD5", sid:otest.popId()});
      return otest.add.apply(otest, arguments);
    }
  }

  funx.N = function() {
    if (otest)
      return otest.show.apply(otest, arguments);
    else {
      otest = new ctest;
      //this.CDialog({title:"u5A04u5A77\u6D4B\u8BD5", sid:otest.popId()});
      return otest.show.apply(otest, arguments);
    }
  }

  funx.SS = function() {
    if (otest && otest.popDom().parentElement.parentElement)
      return otest.add.apply(otest, arguments);
    else {
      otest = new ctest;
      this.CDialog({ title: "\u6D4B\u8BD5", sid: otest.popId() });
      return otest.add.apply(otest, arguments);
    }
  }

  funx.NN = function() {
      if (otest && otest.popDom().parentElement.parentElement)
        return otest.show.apply(otest, arguments);
      else {
        otest = new ctest;
        this.CDialog({ title: "\u6D4B\u8BD5", sid: otest.popId() });
        return otest.show.apply(otest, arguments);
      }
    }
    /**
     * [CDialog description]
     * @param {[type]} o [description]
     * o {
     *     title:
     *     scontent:
     *     fcontent:
     *     fbtn:
     *     closebtn:true
     *     sid:
     * }
     */

  funx.CDialog = function(o) {
    var title = o.title,
      content = o.fcontent ? o.fcontent() : "",
      btn = o.fbtn ? o.fbtn() : "";

    var spref = "_dialog_";
    var isactive = 0;
    var ostart;
    if (ostart) {
      ostart.x += 20;
      ostart.y += 20;
    } else {
      ostart = {
        x: 200,
        y: 120
      };
    }

    function createDiv() {
      return document.createElement("div");
    }
    var dialog = createDiv();
    dialog.className = spref + "dialog";

    var dhead = createDiv();
    dhead.innerHTML = "<div class='" + spref + "title'>" + title + "</div>";
    var dclose = createDiv();
    dclose.className = spref + "close";
    dclose.innerHTML = "X";
    T.addEvent(dclose, "click", function() {
      document.body.removeChild(dialog);
    });
    dhead.className = spref + "head";
    dhead.appendChild(dclose);

    dialog.appendChild(dhead);

    var dcontent = null;
    if (o.fcontent)
      dialog.appendChild(o.fcontent(dialog));
    else if (o.scontent != null) {
      dcontent = createDiv();
      dcontent.className = spref + "content";
      dcontent.innerHTML = o.scontent;
      dialog.appendChild(dcontent);
    } else if (o.sid) {
      dcontent = T.id(o.sid);
      if (dcontent) {
        dcontent.parentNode.removeChild(dcontent);
        dcontent.className = spref + "content";
        dialog.appendChild(dcontent);
      }
    }

    if (o.fbtn)
      dialog.appendChild(o.fbtn(dialog));

    document.body.appendChild(dialog);

    T.addEvent(dhead, "mousedown", function(event) {
      move(event, 1);
    });

    T.addEvent(document.body, "mousemove", function(event) {
      move(event, 0);
    });

    T.addEvent(document.body, "mouseup", function(event) {
      move(event, 2);
    });

    reposition(($(window).width() - $(dialog).width()) / 2,
      ($(window).height() - $(dialog).height()) / 2);
    var opos = ostart;

    function move(event, mark) {
      if (mark == 1) {
        isactive = 1;
        opos.x = event.clientX;
        opos.y = event.clientY;
      } else if (mark == 2) {
        isactive = 0;
      } else if (mark == 0 && isactive == 1) {
        var $dom = $(dialog);
        reposition($dom.offset().left + event.clientX - opos.x,
          $dom.offset().top + event.clientY - opos.y)
        opos.x = event.clientX;
        opos.y = event.clientY;
      }
    }

    function reposition(x, y) {
      var $dom = $(dialog);
      $dom.css("left", x);
      $dom.css("top", y);
    }

    return dcontent;
  }

  T.extend(funx);

  var Xrandom = function(str) {
    return new random(str);
  };

  function random(str) {
    this.schar_ = str || "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
  }

  random.prototype.gen = function(isize) {
    var res = "";
    var schar = this.schar_;
    var charLen = schar.length;
    for (var i = 0; i < isize; i++) {
      var index = Math.round(Math.random() * (charLen - 1));
      res += schar.charAt(index);
    }
    return res;
  }

  random.prototype.rand = function(imin, imax) {
    var inum = imin;
    if (imax != null) {
      inum = imax - imin;
      return imin + Math.round(Math.random() * inum);
    } else
      return Math.round(Math.random() * inum);
  }

  T.extend(Xrandom, {
    cut: function(str, isize) {
      var atip = [];
      var icount = Math.ceil(str.length / isize);
      for (var i = 0; i < icount; i++)
        atip.push(str.substr(i * isize, isize));
      return atip;
    },
    genIp: function(shex) {
      var s1 = shex ? shex : Xr("0123456789ABCDEF").gen(8);
      var s = parseInt(s1, 16).toString(2);
      /**
       * fill "0" when length less than 32
       */
      if (s.length < 32) {
        var k = 32 - s.length;
        var stmp = "";
        for (var i = 0; i < k; i++)
          stmp += "0";
        s = stmp + s;
      }
      var aipCut = this.cut(s, 8);
      var aipCutTmp = [];
      for (var i = 0; i < aipCut.length; i++)
        aipCutTmp[i] = parseInt(aipCut[i], 2).toString();
      aipCut = null;
      return aipCutTmp.join(".");
    },
    genChinese: function(shex) {
      var s = (shex ? shex : "\\u" + (parseInt("4e00", 16) + Xr().rand(20901)).toString(16));

      var s2 = s.replace(/\\u([0-9a-zA-Z]{4})/g, "%u$1");
      return unescape(s2);
    }
  });

  function Request(url, options) {
    var xmlhttp;
    if (window.XMLHttpRequest) // code for IE7+, Firefox, Chrome, Opera, Safari
      xmlhttp = new XMLHttpRequest();
    else // code for IE6, IE5
      xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");

    options.type = options.type || "GET";

    var vparam = options.data;

    var data;
    if (!vparam)
      data = "";
    else if (typeof vparam === "string") {
      data = vparam;
      vparam = null;
    } else if (typeof vparam === "object") {
      data = "";
      for (var param in vparam) {
        var value = vparam[param];
        data += param + "=" + encodeURIComponent(value) + "&";
      }
      data += "/=" + Math.random();
    } else
      data = "";

    xmlhttp.open(options.type, url);

    if (options.head) {
      for (var param in options.head) {
        xmlhttp.setRequestHeader(param, options.head[param]);
      }
    }

    var jdata,
      fcallback;

    try {
      xmlhttp.send(data);
    } catch (e) {
      PopCheckError("可能由于网络原因，您的请求未能发送，请检查连接后重试。");
      return;
    }

    xmlhttp.onreadystatechange = function() {
      if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
        var sresponse = xmlhttp.responseText;
        //var vReturnHeaders = xmlhttp.getAllResponseHeaders();
        //var sreturnMIMEtype = xmlhttp.getResponseHeader("Content-Type");
        //if (/json/.test(sreturnMIMEtype)) //判断返回类型
        if (1) {
          try {
            jdata = $.parseJSON(sresponse.replace(/\t/g, ""));
          } catch (e) //返回的不是正确的json字符串, 不能解析
          {
            return;
          }
        }
        if (fcallback)
          fcallback(jdata || sresponse, true);
      }
    };

    return {
      success: function(call) {
        fcallback = call;
      }
    }
  }

  T.extend({ Xr: Xrandom, ajax: Request });

  return T;

}))
